home *** CD-ROM | disk | FTP | other *** search
/ Complete Linux / Complete Linux.iso / docs / apps / database / ingres04.lzh / source / equel / grammar.y < prev    next >
Encoding:
Text File  |  1992-11-19  |  20.7 KB  |  1,304 lines

  1. /*
  2. **  GRAMMAR.Y -- Equel 6.2 grammar
  3. **
  4. **    Yacc grammar and semantic rules for Quel
  5. **    embedded in C.
  6. **
  7. **    The grammar is organized in the following manner:
  8. **        a) control structure
  9. **        b) quel statments
  10. **        c) equel statements
  11. **        d) declaration and use of C vars
  12. **        e) special objects
  13. **        f) expressions
  14. **        g) keywords
  15. **        h) noise words and punctuation
  16. **    Within a single classification, major objects are ordered
  17. **    alphabetically, and minor objects under the major ones they
  18. **    are in.
  19. **
  20. **    Side Effects:
  21. **        performs the translation of an Equel program into
  22. **        a C program with calls on the Equel run-time
  23. **        support
  24. **
  25. **    NOTE:
  26. **        There are two shift/reduce conflicts associated
  27. **        with the non-terminals "[o_]gen_while". It is resolved
  28. **        correctly by yacc.
  29. */
  30.  
  31.  
  32.  
  33. %{
  34.     /* STANDARD SCANNER & PARSER GLOBALS */
  35.  
  36. # include    "constants.h"
  37. # include    <stdio.h>
  38. # include    "globals.h"
  39.  
  40.  
  41. %}
  42. %union
  43. {
  44.     struct disp_node    *u_dn;
  45. };
  46.  
  47.  
  48.     /* QUEL keywords */
  49. %token    <u_dn>    APPEND        COPY         CREATE        DEFINE        
  50. %token    <u_dn>    DELETE        DELIM         DESTROY        HELP
  51. %token    <u_dn>    INDEX        MODIFY         PRINT        INTEGRITY    
  52. %token    <u_dn>    RANGE        REPLACE        RETRIEVE    SAVE        
  53. %token    <u_dn>    UNIQUE        UNUSE        USE        PERMIT        
  54. %token  <u_dn>    VIEW
  55.  
  56.     /* special embedded QUEL commands */
  57. %token    <u_dn>    INGRES        EXIT        PARAM
  58.  
  59.     /* C variable usages */
  60. %token    <u_dn>    TYPE        ALLOC        STRUCT        STRUCT_VAR
  61.  
  62.     /* QUEL noise words */
  63. %token    <u_dn>    ALL        BY        FROM        IN
  64. %token    <u_dn>    INTO        IS        OF        ON
  65. %token    <u_dn>    ONTO        TO        WHERE        UNTIL
  66. %token    <u_dn>    AT
  67.  
  68.     /* constants */
  69.  
  70. %token    <u_dn>    NAME        SCONST        I2CONST        I4CONST
  71. %token    <u_dn>    F8CONST        C_CODE
  72.  
  73.     /* punctuation */
  74. %token    <u_dn>    COMMA        LPAREN        RPAREN        PERIOD
  75. %token    <u_dn>    QUOTE        BGNCMNT        ENDCMNT        LBRACE
  76. %token    <u_dn>    RBRACE        LBRKT        RBRKT        NONREF
  77. %token    <u_dn>    SEMICOL        POINTER        COLON        DOLLAR
  78. %token    <u_dn>    PCT
  79.  
  80.     /* operator classes */
  81. %token    <u_dn>    UOP
  82. %token    <u_dn>    BOP
  83. %token    <u_dn>    UAOP
  84. %token    <u_dn>    BDOP
  85. %token    <u_dn>    EOP
  86. %token    <u_dn>    LBOP        LUOP
  87. %token    <u_dn>    FOP        FBOP
  88. %token    <u_dn>    AOP
  89.  
  90.     /* define ascending precedence for operators */
  91.  
  92. %left    LBOP
  93. %left    LUOP
  94. %left    UAOP
  95. %left    BOP        LBRKT
  96. %left    UOP
  97. %nonassoc        unaryop
  98.  
  99.     /* non-teriminal type info */
  100. %type <u_dn>        endblock
  101. %type <u_dn>        c_variable
  102. %type <u_dn>        cvarx
  103. %type <u_dn>        struct_var
  104. %type <u_dn>        ptr
  105. %type <u_dn>        selector_part
  106. %type <u_dn>        str_var_key
  107. %type <u_dn>        id
  108.  
  109.  
  110.  
  111. %%
  112. %{
  113.     struct cvar    *cvarp;
  114. %}
  115.  
  116. /*
  117.  * Program Control Structure
  118.  */
  119.  
  120. program:    program statement = 
  121.         {
  122.             /* for each "statement", free the symbol space
  123.              * used by that query (lookahed space must not
  124.              * be freed), and catch up on output lines
  125.              */
  126.             symspfree();
  127.             equate_lines();
  128.         }
  129.     |    ;
  130. ;
  131. statement:    startquel quel_statement = 
  132.         {
  133.             w_sync();
  134.             /* the purpose of the actions for startquel
  135.              * and this action is to make each query
  136.              * a single compound C statement (if (x) "{query}")
  137.              */
  138.             w_op("}");
  139.         }
  140.     |    startquel equel_statement =
  141.         {
  142.             end_quote();
  143.             w_op("}");
  144.         }
  145.     |    c_code    
  146.     |     declaration     
  147.     |     error
  148. ;
  149. startquel:    =
  150.             w_op("{");
  151. ;
  152. /*
  153.  * C_CODE is a token returned by the lexical analyzer
  154.  * when it recognizes that the following line is not
  155.  * equel code. On the NEXT call to the lexical analyzer,
  156.  * the code will be copied from the source to the output file.
  157.  */
  158. c_code:     C_CODE    
  159.     |    beginblock =
  160.             Block_level += 1;
  161.     |    endblock =
  162.         {
  163.             if (Block_level == 0)
  164.                 yyserror("extra '}'", $1);
  165.             else if ((Block_level -= 1) == 0)
  166.             {
  167.                 freecvar(&C_locals);
  168.                 freecvar(&F_locals);
  169.             }
  170.         }
  171. ;
  172.  
  173.     /* the %prec is to resolve conflicts with the { after a
  174.      * "tupret".
  175.      */
  176. beginblock:    LBRACE  %prec LBOP =
  177.             w_op($1->d_elm);
  178. ;
  179. endblock:    RBRACE =
  180.             w_op($1->d_elm);
  181. ;
  182. quel_statement: append     
  183.     |    copy 
  184.     |     create     
  185.     |    delete 
  186.     |    delim
  187.     |     destroy     
  188.     |    help 
  189.     |     index     
  190.     |     integrity     
  191.     |    modify 
  192.     |    permit
  193.     |    print 
  194.     |    range 
  195.     |    replace 
  196.     |    retrieve 
  197.     |    save 
  198.     |    unuse
  199.     |    use
  200.     |    view
  201. ;
  202.  
  203.     /* commands particular to Equel */
  204.  
  205. equel_statement:append_p
  206.         {
  207.             w_sync();
  208.         }
  209.     |    copy_p
  210.     |      create_p
  211.         {
  212.             w_sync();
  213.         }
  214.     |     exit     
  215.     |     ingres     
  216.     |    replace_p
  217.         {
  218.             w_sync();
  219.         }
  220.     |    retrieve_p
  221.     |    tupret
  222.     |    view_p
  223. ;
  224. /*
  225.  * QUEL statements 
  226.  */
  227.  
  228. append:        append_key apclause tlclause qualclause    
  229. ;
  230. apclause:    apkword id    
  231. ;
  232.  
  233. copy:         copy_key id lparen ctl rparen cp_kword filename 
  234.     |     copy_key id lparen rparen cp_kword filename
  235. ;
  236. filename:    sconst
  237.     |    id 
  238. ;
  239.  
  240. create:        create_key id lparen ctl rparen
  241. ;
  242.  
  243. delete:        delete_key delclause qualclause    
  244. ;
  245. delclause:    delnoise id        
  246. ;
  247.  
  248. delim:        define_key delim_key id lparen id comma sconst rparen
  249. ;
  250.  
  251. destroy:    destroy_key idlist
  252.     |    destroy_key integ_permit id int_list_all
  253.     |    destroy_key delim_key id
  254. ;
  255. integ_permit:    integ_key
  256.     |    permit_key
  257. ;
  258. int_list_all:    int_list
  259.     |    all
  260. ;
  261.  
  262. help:        help_key    
  263.     |    help_key all
  264.     |    help_key hlist
  265.     |    help_key delim_key
  266.     |    help_key delim_key hlist
  267.     |    help_key int_perm_view idlist
  268. ;
  269. hlist:        hparam
  270.     |    hlist comma hparam
  271. ;
  272. hparam:        id 
  273.     |    sconst
  274. ;
  275. int_perm_view:    integ_permit
  276.     |    view_key
  277. ;
  278.  
  279. index:        index_key id is id lparen idlist rparen
  280. ;
  281.  
  282. integrity:    define_key integ_key integnoise id isnoise qual
  283. ;
  284.  
  285. modify:        modify_key id to id on modkeylist density
  286.     |    modify_key id to id
  287. ;
  288. modkeylist:    modkey
  289.     |    modkeylist comma modkey
  290. ;
  291. modkey:        id
  292.     |    id colon id
  293. ;
  294. density:    where modfill
  295.     |    ;
  296. ;
  297. modfill:    id is mod_var
  298.     |    modfill comma id is mod_var
  299. ;
  300.     /* mod_var can be an integer constant or var, or a string var
  301.      * or a quel name
  302.      */
  303. mod_var:    I2CONST =
  304.             w_con(I2CONST, $1->d_elm);
  305.     |    c_variable =
  306.         {
  307.             if ($1)
  308.             {
  309.                 if (!Cvarp)
  310.                     w_key($1->d_elm);
  311.                 else if (Fieldp && Fieldp->c_type == opINT
  312.                     || Cvarp->c_type == opINT)
  313.                         w_var(Cv_display, opINT);
  314.                 else if (Fieldp && Fieldp->c_type == opSTRING 
  315.                     || Cvarp->c_type == opSTRING)
  316.                         w_var(Cv_display, opIDSTRING);
  317.                 else
  318.                     yyserror("in MODIFY, qual var must be in or string",
  319.                     $1);
  320.             }
  321.             else
  322.                 yyserror("bad modify qualification", 0);
  323.             free_display(Cv_display);
  324.             Cvarp = Fieldp = 0;
  325.         }
  326. ;
  327.  
  328. permit:        def_perm permit_list on_of_to id perm_tl
  329.             perm_who perm_term perm_time perm_day qualclause
  330. ;
  331. def_perm:    define_key permit_key 
  332. ;
  333. permit_list:    permlistelm
  334.     |    permit_list comma permlistelm
  335. ;
  336. permlistelm:    RETRIEVE =
  337.             w_key($1->d_elm);
  338.     |    APPEND =
  339.             w_key($1->d_elm);
  340.     |    DELETE =
  341.             w_key($1->d_elm);
  342.     |    REPLACE = 
  343.             w_key($1->d_elm);
  344.     |    all
  345. ;
  346. on_of_to:    on
  347.     |    of
  348.     |    to
  349. ;
  350. perm_tl:    lparen idlist rparen
  351.     |    ;
  352. ;
  353. perm_who:    to id
  354.     |    to all
  355.     |    ;
  356. ;
  357. perm_term:    at id
  358.     |    at all
  359.     |    ;
  360. ;
  361. perm_time:    from integer colon integer to
  362.             integer colon integer
  363.     |    ;
  364. ;
  365. perm_day:    on id to id
  366.     |    ;
  367. ;
  368.  
  369. print:        print_key idlist 
  370. ;
  371.  
  372. range:        range_of id is id    
  373. ;
  374.  
  375. replace:    replace_key repclause tlclause qualclause    
  376. ;
  377. repclause:    repkword id    
  378. ;
  379.  
  380. retrieve:    retrieve_key resclause tlclause qualclause    
  381. ;
  382. resclause:    retkword id    
  383. ;
  384.  
  385. save:        save_key id until date
  386. ;
  387. date:        id integer integer
  388. ;
  389.  
  390. unuse:        unuse_key id
  391. ;
  392.  
  393. use:        use_key id
  394. ;
  395.  
  396. view:        define_key view_key id tlclause qualclause
  397. ;
  398.  
  399. /*
  400.  * Statements Particular to Equel
  401.  */
  402.  
  403. append_p:    append_p_key apclause param_tl qualclause
  404. ;
  405.  
  406. copy_p:        copy_p_key id param_tl fr_in_id filename
  407. ;
  408. fr_in_id:    cp_kword
  409.     |    c_variable =
  410.         {
  411.             if ($1 && Cvarp)
  412.             {
  413.                 if (Fieldp && Fieldp->c_type != opSTRING
  414.                    || !Fieldp && Cvarp->c_type != opSTRING)
  415.                     yyserror("string var expected for from/into in COPY",
  416.                     $1);
  417.                 else
  418.                     w_var(Cv_display, opIDSTRING);
  419.             }
  420.             else
  421.                 yyserror("into/from expected in COPY", $1);
  422.             free_display(Cv_display);
  423.             Fieldp = Cvarp = 0;
  424.         }
  425. ;
  426.  
  427. create_p:    create_p_key id param_tl
  428. ;
  429.  
  430. exit:        EXIT = 
  431.         { 
  432.             Opflag = mdEXIT;
  433.             w_new("IIexit();"); 
  434.         }
  435. ;
  436.  
  437. ingres:        ingres_key param_list = 
  438.             w_op(");"); 
  439. ;
  440. param_list:    param =
  441.             w_op("0");
  442.     |    param param_list
  443. ;
  444. param:        id  =
  445.             w_op(",");
  446.     |    SCONST =
  447.         {
  448.             w_string($1->d_elm, 0);
  449.             w_op(",");
  450.         }
  451. ;
  452.  
  453. replace_p:    replace_p_key repclause param_tl qualclause
  454. ;
  455.  
  456. retrieve_p:    retrieve_p_key resclause param_tl qualclause
  457. ;
  458.  
  459. tupret:        tupret_keyw xc_code =
  460.             w_flush();
  461.     |    tupret_p o_xc_code =
  462.             w_flush();
  463. ;
  464. tupret_keyw:    retrieve_key unique c_tlclause qualclause    =
  465.         {
  466.             w_new("IIsetup();");
  467.         }
  468. ;
  469. unique:     UNIQUE =
  470.         {
  471.             Opflag = mdTUPRET;
  472.             w_key($1->d_elm);
  473.         }
  474.     |    =
  475.             Opflag = mdTUPRET;
  476. ;
  477. c_tlclause:    lparen    c_tlist    rparen     
  478. ;
  479. c_tlist:    c_tlelm 
  480.     |     c_tlelm comma c_tlist  
  481. ;
  482. c_tlelm:    reduc cvar is_key afcn     
  483. ;
  484. reduc:        =
  485.             Opflag = mdCTLELM;
  486. ;
  487. xc_code:    LBRACE gen_while c_code RBRACE %prec LBRACE =
  488.             w_op("}");
  489.     |    gen_while %prec LBOP =
  490.             w_op("}");
  491. ;
  492. gen_while:    =
  493.         {
  494.             w_new("while(IIn_get(");
  495.             w_file();
  496.             w_op(")){");
  497.             w_ret();
  498.             free_ret();
  499.             w_op("if(IIerrtest())continue;");
  500.             equate_lines();
  501.         }
  502. ;
  503. o_xc_code:    LBRACE  o_gen_while c_code RBRACE %prec LBRACE =
  504.             w_op("}");
  505.     |    o_gen_while %prec LBOP =
  506.             w_op("}");
  507. ;
  508. o_gen_while:    =
  509.         {
  510.             w_new("while(IIgettup(");
  511.             w_file();
  512.             w_op(")){");
  513.             equate_lines();
  514.         }
  515. ;
  516. tupret_p:    tupret_p_key unique param_tl qualclause =
  517.         {
  518.             w_new("IIsetup();");
  519.         }
  520. ;
  521.  
  522. view_p:        PARAM define_key view_key id param_tl qualclause
  523. ;
  524.  
  525. /*
  526.  * Declarations and use of C variables
  527.  */
  528.  
  529. declaration:    decl_specifer declarator_list SEMICOL    =
  530.         {
  531.             w_op($3->d_elm);
  532.             Type_spec = 0;
  533.         }
  534.     |     decl_specifer SEMICOL = 
  535.         { 
  536.             w_op($2->d_elm);
  537.             Type_spec = 0;
  538.         }
  539. ;
  540. decl_specifer:    type_specifier    
  541.     |     sc_specifier    
  542.     |     type_specifier sc_specifier    
  543.     |     sc_specifier type_specifier    
  544.     |    struct_dec =
  545.         {
  546.             Struct_flag = 0;
  547.             Type_spec = opSTRUCT;
  548.         }
  549.     |    sc_specifier struct_dec =
  550.         {
  551.             Struct_flag = 0;
  552.             Type_spec = opSTRUCT;
  553.         }
  554. ;
  555. sc_specifier:    ALLOC    =
  556.         {
  557.             Opflag = mdDECL;
  558.             w_key($1->d_elm);
  559.             /* in case the default "int" should be assumed,
  560.              * the Type_spec is set up for it, if a previous
  561.              * type hasn't been given
  562.              */
  563.             if (!Type_spec)
  564.                 Type_spec = opINT;
  565.         }
  566. ;
  567. type_specifier:    TYPE    =
  568.         {
  569.             Opflag = mdDECL;
  570.             w_key($1->d_elm);
  571.             Type_spec = Opcode;
  572.         }
  573. ;
  574. struct_dec:    struct_name field_declaration 
  575.     |    struct_name
  576.     |    struct_key field_declaration
  577. ;
  578. struct_name:    struct_key NAME =
  579.             w_key($2->d_elm);
  580. ;
  581. field_declaration:    lbrace field_seq RBRACE =
  582.         {
  583.             w_op($3->d_elm);
  584.             Type_spec = 0;
  585.         }
  586. ;
  587. field_seq:    field_seq field
  588.     |    ;
  589. ;
  590. field:        type_specifier declarator_list SEMICOL =
  591.         {
  592.             w_op($3->d_elm);
  593.             Type_spec = 0;
  594.         }
  595.     |    C_CODE
  596. ;
  597. declarator_list:    cvar_dec
  598.     |    declarator_list comma cvar_dec
  599. ;
  600. cvar_dec:    cvarx =
  601.         {
  602.             if (Type_spec == opSTRING)
  603.                 Indir_level -= 1;
  604.             if (Struct_flag)
  605.                 decl_field($1->d_elm, Type_spec,
  606.                     Indir_level, Block_level);
  607.             else
  608.                 decl_cvar($1->d_elm, Type_spec,
  609.                     Indir_level, Block_level);
  610.             free_display(Cv_display);
  611.             Indir_level = Field_indir = 0;
  612.             Fieldp = Cvarp = 0;
  613.         }
  614. ;
  615. c_variable:    cvarx =
  616.         {
  617.             $$ = $1;
  618.             if (Cvarp && Cvarp->c_indir != Indir_level)
  619.             {
  620.                 yyserror("bad indirection on a C variable", $1);
  621.                 $$ = 0;
  622.             }
  623.             Indir_level = Field_indir = 0;
  624.         }
  625.     |    NONREF NAME =
  626.         {
  627.             enter_display(Cv_display, salloc($1->d_elm));
  628.             Cvarp = Fieldp = 0;
  629.             $$ = $2;
  630.         }
  631.     |    NONREF STRUCT_VAR =
  632.         {
  633.             enter_display(Cv_display, salloc($1->d_elm));
  634.             Cvarp = Fieldp = 0;
  635.             $$ = $2;
  636.         }
  637.     |    struct_var =
  638.         {
  639.             if (!Fieldp)
  640.             {
  641.                 yyserror("undeclared field", $1);
  642.                 $$ = $<u_dn>0;
  643.             }
  644.             else if (Fieldp->c_indir != Field_indir)
  645.             {
  646.                 yyserror("bad indirection on a structure's field",
  647.                 $1);
  648.                 $$ = 0;
  649.             }
  650.             if (Cvarp->c_indir != Indir_level)
  651.             {
  652.                 yysemerr("bad indirection a structure variable",
  653.                 Cvarp->c_indir);
  654.                 $$ = 0;
  655.             }
  656.             Indir_level = Field_indir = 0;
  657.         }
  658. ;
  659. struct_var:    ptr struct_var    %prec unaryop =
  660.         {
  661.             if ($1->d_elm[1] == '*')
  662.                 Field_indir += 1;
  663.             Field_indir += 1;
  664.             $$ = $2;
  665.         }
  666.     |    struct_var arraysub    %prec LBRKT =
  667.             Field_indir += 1;
  668.     |    str_var_key selector_part
  669. ;
  670. str_var_key:    STRUCT_VAR =
  671.         {
  672.             Cvarp = getcvar($1->d_elm);
  673.             enter_display(Cv_display, salloc($1->d_elm));
  674.         }
  675. ;
  676. selector_part:    arraysub selector_part =
  677.         {
  678.             Indir_level += 1;
  679.             $$ = $2;
  680.         }
  681.     |    select_op NAME =
  682.         {
  683.             enter_display(Cv_display, salloc($2->d_elm));
  684.             Fieldp = getfield($2->d_elm);
  685.             $$ = $2;
  686.         }
  687. ;
  688. select_op:    PERIOD =
  689.             enter_display(Cv_display, salloc($1->d_elm));
  690.     |    POINTER =
  691.         {
  692.             enter_display(Cv_display, salloc($1->d_elm));
  693.             Indir_level += 1;
  694.         }
  695. ;
  696.  
  697. /* use of a C variable */
  698. cvar:        c_variable =    
  699.         {
  700.             if ($1)
  701.             {
  702.                 if (!Fieldp && ! Cvarp)
  703.                 {
  704.                     if (!Field_indir && !Indir_level
  705.                       && (sequal($1->d_elm, "dba")
  706.                         || sequal($1->d_elm, "usercode")))
  707.                         /* constant operator COP */
  708.                         w_key($1->d_elm);
  709.                     else
  710.                         yyserror("C var expected", $1);
  711.                 }
  712.                 else if (Opflag == mdCTLELM)
  713.                 {
  714.                     w_con(NAME,
  715.                       Fieldp ? Fieldp->c_id: Cvarp->c_id);
  716.                     enter_ret(Cv_display,
  717.                       Fieldp ? Fieldp->c_type: Cvarp->c_type);
  718.                 }
  719.                 else
  720.                     w_var(Cv_display,
  721.                       Fieldp ? Fieldp->c_type: Cvarp->c_type);
  722.             }
  723.             free_display(Cv_display);
  724.             Fieldp = Cvarp = 0;
  725.             Indir_level = Field_indir = 0;
  726.         }
  727. cvarx:         NAME =
  728.         {
  729.             if (Opflag == mdDECL)
  730.                 w_con(NAME, $1->d_elm);
  731.             else
  732.             {
  733.                 Cvarp = getcvar($1->d_elm);
  734.                 enter_display(Cv_display, salloc($1->d_elm));
  735.             }
  736.         }
  737.     |    ptr cvarx %prec unaryop =
  738.         {
  739.             if ($1->d_elm [1] == '*')
  740.                 Indir_level += 1;
  741.             Indir_level += 1;
  742.             $$ = $2;
  743.         }
  744.     |    cvarx arraysub    %prec LBRKT =
  745.         {
  746.             Indir_level += 1;
  747.         }
  748. ;
  749. ptr:        BOP =
  750.         {
  751.             if (!sequal($1->d_elm, "*") && !sequal((struct disp_node *)($1)->d_elm, "**"))
  752.                 yyserror(Opflag == mdDECL ?
  753.                 "invalid operator in declaration":
  754.                 "invalid operator in C variable",
  755.                 $1);
  756.             if (Opflag == mdDECL)
  757.                 w_op($1->d_elm);
  758.             else
  759.                 enter_display(Cv_display, salloc($1->d_elm));
  760.         }
  761. ;
  762. arraysub:    LBRKT =
  763.         {
  764.             if (Opflag == mdDECL)
  765.                 eat_display(0, '[', ']');
  766.             else
  767.                 eat_display(Cv_display, '[', ']');
  768.         }
  769. ;
  770.  
  771. /*
  772.  * Special Objects used throughout grammar
  773.  */
  774.  
  775. id:        c_variable =
  776.         {
  777.             if ($1)
  778.             {
  779.                 if (Cvarp)
  780.                 {
  781.                     if (Fieldp && Fieldp->c_type != opSTRING
  782.                        || !Fieldp && Cvarp->c_type != opSTRING)
  783.                         yyserror("string var expected", $1);
  784.                     else if (Opflag == mdFILENAME)
  785.                         w_var(Cv_display, opSTRING);
  786.                     else if (Opflag == mdINGRES)
  787.                         w_display(Cv_display);
  788.                     else
  789.                         w_var(Cv_display, opIDSTRING);
  790.                 }
  791.                 else if (Opflag == mdINGRES)
  792.                     w_string($1->d_elm, 0);
  793.                 else if (Opflag == mdFILENAME)
  794.                     yyserror("file for a COPY must be a string or string variable",
  795.                     $1);
  796.                 else
  797.                     w_key($1->d_elm);
  798.             }
  799.             free_display(Cv_display);
  800.             Fieldp = Cvarp = 0;
  801.         }
  802. ;
  803.  
  804. idlist:        id
  805.     |    idlist comma id
  806. ;
  807.  
  808. integer:    I2CONST    =
  809.             w_con(I2CONST, $1->d_elm);
  810.     |    c_variable =
  811.         {
  812.             if ($1)
  813.             {
  814.                 if (Cvarp)
  815.                     if (Fieldp && Fieldp->c_type == opINT
  816.                        || Cvarp->c_type == opINT)
  817.                         w_var(Cv_display, opINT);
  818.                     else
  819.                         yyserror("integer variable required",
  820.                         $1);
  821.                 else
  822.                     yyserror("integer variable required", $1);
  823.             }
  824.             free_display(Cv_display);
  825.         }
  826. ;
  827.  
  828. int_list:    integer
  829.     |    int_list comma integer
  830. ;
  831.  
  832. param_tl:    LPAREN =
  833.         {
  834.             w_op("(");
  835.             end_quote();
  836.             if (Opflag == mdTUPRET)
  837.                 w_key("IIw_left");
  838.             else
  839.                 w_key("IIw_right");
  840.             eat_display(0, '(', ')');
  841.             w_op(";");
  842.             begin_quote();
  843.             w_op(")");
  844.  
  845.         }
  846. ;
  847.  
  848. qualclause:    where qual    
  849.     |    where c_variable =
  850.         {
  851.             if (!$2 || !Cvarp)
  852.                 yyserror("C var (string) expected", $2);
  853.             else if (Fieldp && Fieldp->c_type == opSTRING
  854.                 || Cvarp->c_type == opSTRING)
  855.             {
  856.                 w_raw(" ");
  857.                 end_quote();
  858.                 w_op("IIwrite(");
  859.                 w_display(Cv_display);
  860.                 w_op(");");
  861.                 Lastc = KEYCHAR;
  862.             }
  863.             else
  864.                 yyserror("var must be string valued for qualification",
  865.                 $2);
  866.             free_display(Cv_display);
  867.             Cvarp = Fieldp = 0;
  868.         }
  869.     |    ;
  870. ;
  871. qual:        lparen qual rparen    
  872.     |     luop qual        %prec LUOP    
  873.     |     qual lbop qual        %prec LBOP    
  874.     |     clause    
  875.     |     ;
  876. ;
  877. clause:    afcn rop afcn    
  878.     |     afcn rop afcn bdop afcn    
  879. ;
  880. ctl:        id is id 
  881.     |     ctl comma id is id 
  882. ;
  883.  
  884. sconst:        SCONST = 
  885.             w_con(SCONST, $1->d_elm);
  886. ;
  887.  
  888. tlclause:    lparen tlist rparen    
  889. ;
  890. tlist:        tlelm    
  891.     |    tlelm comma tlist    
  892. ;
  893. tlelm:        id is_key afcn    
  894.     |    attrib    
  895. ;
  896.  
  897. /*
  898.  * Expressions
  899.  */
  900.  
  901. afcn:        aggrfcn     
  902.     |     aggr     
  903.     |     attribfcn  
  904.     |     afcn bop afcn     %prec BOP  
  905.     |    afcn uaop afcn  %prec UAOP
  906.     |     lparen afcn rparen  
  907.     |     uop afcn     %prec unaryop    
  908.     |     fop lparen afcn rparen  
  909.     |     fbop lparen afcn comma afcn rparen    
  910. ;
  911. aggr:        aop lparen afcn qualclause rparen    
  912. ;
  913. aggrfcn:     aop lparen afcn by aseq qualclause rparen
  914. ;
  915. attribfcn:    I2CONST    = 
  916.             w_con(I2CONST, $1->d_elm);
  917.     |     I4CONST    = 
  918.             w_con(I4CONST, $1->d_elm);
  919.     |    F8CONST    = 
  920.             w_con(F8CONST, $1->d_elm);
  921.     |     SCONST    = 
  922.             w_con(SCONST, $1->d_elm);
  923.     |    cvar
  924.     |     attrib    
  925. ;
  926. aseq:        aseq comma afcn  
  927.     |    afcn    
  928. ;
  929. attrib:        id period id    
  930.     |    id period all=
  931.         {
  932.             if (Opflag != mdVIEW && Opflag != mdRETRIEVE
  933.                && Opflag != mdAPPEND)
  934.                 yyserror(
  935.                 "'all' applied to this range variable illegal in this kind of statement",
  936.                 $1);
  937.         }
  938.     |    attrib stringpart
  939. ;
  940. stringpart:    leftclose subelm rightclose
  941.     |    leftclose grpelm rightclose
  942. ;
  943. leftclose:    pct
  944.     |    lparen
  945. ;
  946. rightclose:    pct  
  947.     |    rparen
  948. ;
  949. subelm:        integer nameprt
  950.     |    integer nameprt dollar
  951.     |    dollar
  952.     |    nameprt
  953.     |    nameprt dollar
  954. ;
  955. grpelm:        subelm comma subelm
  956. ;
  957. nameprt:    id
  958.     |     sconst
  959. ;
  960. lbop:        LBOP    = 
  961.             w_key($1->d_elm);
  962. ;
  963. luop:        LUOP    = 
  964.             w_key($1->d_elm);
  965. ;
  966. bdop:        BDOP    = 
  967.             w_op($1->d_elm);
  968. ;
  969. rop:        EOP    = 
  970.             w_op($1->d_elm);
  971.     |     BDOP    = 
  972.             w_op($1->d_elm);
  973.     |     IS    = 
  974.             w_op("=");
  975. ;
  976. uop:        UOP = 
  977.             w_op($1->d_elm);
  978. ;
  979. fop:        FOP = 
  980.             w_key($1->d_elm);
  981. ;
  982. fbop:        FBOP = 
  983.             w_key($1->d_elm);
  984. ;
  985. bop:        BOP = 
  986.             w_op($1->d_elm);
  987.     |     UOP = 
  988.             w_op($1->d_elm);
  989. ;
  990. by:        BY =
  991.             w_key($1->d_elm);
  992. ;
  993. aop:        AOP = 
  994.             w_key($1->d_elm);
  995. ;
  996. uaop:        UAOP =
  997.             w_key($1->d_elm);
  998. ;
  999.     
  1000. /*
  1001.  * Keywords
  1002.  */
  1003.  
  1004. append_p_key:    PARAM APPEND =
  1005.         {
  1006.             begin_quote();
  1007.             w_key($2->d_elm);
  1008.             Opflag = mdAPPEND;
  1009.         }
  1010. ;
  1011. append_key:    APPEND    =
  1012.         {
  1013.             Opflag = mdAPPEND;
  1014.             begin_quote();
  1015.             w_key($1->d_elm);
  1016.         }
  1017. ;
  1018. copy_key:    COPY    =
  1019.         {
  1020.             Opflag = mdCOPY;
  1021.             begin_quote();
  1022.             w_key($1->d_elm);
  1023.         }
  1024. ;
  1025. copy_p_key:    PARAM COPY =
  1026.         {
  1027.             Opflag = mdCOPY;
  1028.             begin_quote();
  1029.             w_key($2->d_elm);
  1030.         }
  1031. ;
  1032. cp_kword:    INTO    = 
  1033.         {
  1034.             w_key($1->d_elm);
  1035.             Opflag = mdFILENAME;
  1036.         }
  1037.     |     FROM    = 
  1038.         {
  1039.             w_key($1->d_elm);
  1040.             Opflag = mdFILENAME;
  1041.         }
  1042. ;
  1043. create_key:    CREATE    =
  1044.         {
  1045.             Opflag = mdCREATE;
  1046.             begin_quote();
  1047.             w_key($1->d_elm);
  1048.         }
  1049. ;
  1050. create_p_key:    PARAM CREATE =
  1051.         {
  1052.             Opflag = mdCREATE;
  1053.             begin_quote();
  1054.             w_key($2->d_elm);
  1055.         }
  1056. ;
  1057. define_key:    DEFINE =
  1058.         {
  1059.             Opflag = mdDEFINE;
  1060.             begin_quote();
  1061.             w_key($1->d_elm);
  1062.         }
  1063. ;
  1064. delete_key:    DELETE    =
  1065.         {
  1066.             Opflag = mdDELETE;
  1067.             begin_quote();
  1068.             w_key($1->d_elm);
  1069.         }
  1070. ;
  1071. delim_key:    DELIM =
  1072.         {
  1073.             w_key($1->d_elm);
  1074.         }
  1075. ;
  1076. destroy_key:    DESTROY    =
  1077.         {
  1078.             Opflag = mdDESTROY;
  1079.             begin_quote();
  1080.             w_key($1->d_elm);
  1081.         }
  1082. ;
  1083. help_key:    HELP =
  1084.         {
  1085.             Opflag = mdHELP;
  1086.             begin_quote();
  1087.             w_key($1->d_elm);
  1088.         }
  1089. ;
  1090. index_key:    INDEX ON =
  1091.         {
  1092.             Opflag = mdINDEX;
  1093.             begin_quote();
  1094.             w_key($1->d_elm);
  1095.             w_key($2->d_elm);
  1096.         }
  1097. ;
  1098. ingres_key:    INGRES    =
  1099.         {
  1100.             Opflag = mdINGRES;
  1101.             w_new("IIingres(");
  1102.         }
  1103. ;
  1104. integ_key:    INTEGRITY=
  1105.         {
  1106.             if (Opflag == mdDEFINE)
  1107.                 Opflag = mdINTEGRITY;
  1108.             w_key($1->d_elm);
  1109.         }
  1110. ;
  1111. is_key:        IS =
  1112.         { 
  1113.             if (Opflag == mdCTLELM)
  1114.                 Opflag = mdTUPRET;
  1115.             w_op("=");
  1116.         }
  1117.     |     BY = 
  1118.             w_key($1->d_elm);
  1119. ;
  1120. modify_key:    MODIFY    =
  1121.         {
  1122.             Opflag = mdMODIFY;
  1123.             begin_quote();
  1124.             w_key($1->d_elm);
  1125.         }
  1126. ;
  1127. permit_key:    PERMIT=
  1128.         {
  1129.             if (Opflag == mdDEFINE)
  1130.                 Opflag = mdPROT;
  1131.             w_key($1->d_elm);
  1132.         }
  1133. ;
  1134. print_key:    PRINT    =  
  1135.         { 
  1136.             Opflag = mdPRINT;
  1137.             begin_quote();
  1138.             w_key($1->d_elm);
  1139.         }
  1140. ;
  1141. range_of:    RANGE OF = 
  1142.         {
  1143.             Opflag = mdRANGE;
  1144.             begin_quote();
  1145.             w_key($1->d_elm);
  1146.             w_key($2->d_elm);
  1147.         }
  1148. ;
  1149. replace_key:    REPLACE    =
  1150.         {
  1151.             Opflag = mdREPLACE;
  1152.             begin_quote();
  1153.             w_key($1->d_elm);
  1154.         }
  1155. ;
  1156. replace_p_key:    PARAM REPLACE =
  1157.         {
  1158.             begin_quote();
  1159.             Opflag = mdREPLACE;
  1160.             w_key($2->d_elm);
  1161.         }
  1162. ;
  1163. retrieve_key:    RETRIEVE    =
  1164.         {
  1165.             Opflag = mdRETRIEVE;
  1166.             begin_quote();
  1167.             w_key($1->d_elm);
  1168.         }
  1169. ;
  1170. retrieve_p_key: PARAM RETRIEVE =
  1171.         {
  1172.             Opflag = mdRETRIEVE;
  1173.             begin_quote();
  1174.             w_key($2->d_elm);
  1175.         }
  1176. ;
  1177. save_key:    SAVE    =
  1178.         {
  1179.             Opflag = mdSAVE;
  1180.             begin_quote();
  1181.             w_key($1->d_elm);
  1182.         }
  1183. ;
  1184. struct_key:     STRUCT =
  1185.         {
  1186.             Opflag = mdDECL;
  1187.             Struct_flag = 1;
  1188.             w_key($1->d_elm);
  1189.         }
  1190. ;
  1191. tupret_p_key:    PARAM RETRIEVE =
  1192.         {
  1193.             begin_quote();
  1194.             w_key($2->d_elm);
  1195.             Opflag = mdTUPRET;
  1196.         }
  1197. ;
  1198. unuse_key:    UNUSE =
  1199.         {
  1200.             begin_quote();
  1201.             w_key($1->d_elm);
  1202.         }
  1203. ;
  1204. use_key:    USE =
  1205.         {
  1206.             begin_quote();
  1207.             w_key($1->d_elm);
  1208.         }
  1209. ;
  1210. view_key:    VIEW =
  1211.         {
  1212.             if (Opflag == mdDEFINE)
  1213.                 Opflag = mdVIEW;
  1214.             w_key($1->d_elm);
  1215.         }
  1216. ;
  1217.  
  1218. /*
  1219.  * Noise words and punctuation
  1220.  */
  1221.  
  1222. all:        ALL=
  1223.             w_key($1->d_elm);
  1224. ;
  1225. apkword:    INTO    
  1226.     |    ONTO    
  1227.     |    TO    
  1228.     |    ON    
  1229.     |    ;
  1230. ;
  1231. at:        AT =
  1232.             w_key($1->d_elm);
  1233. ;
  1234. colon:        COLON =
  1235.             w_op($1->d_elm);
  1236. ;
  1237. comma:        COMMA    = 
  1238.             w_op($1->d_elm);
  1239. ;
  1240. delnoise:    IN    
  1241.     |    ON    
  1242.     |    FROM    
  1243.     |    ;
  1244. ;
  1245. dollar:        DOLLAR =
  1246.             w_key($1->d_elm);
  1247. ;
  1248. from:        FROM =
  1249.             w_key($1->d_elm);
  1250. ;
  1251. integnoise:    ON
  1252.     |    ONTO
  1253.     |    IN
  1254.     |    OF
  1255. ;
  1256. is:        IS    = 
  1257.             w_op("=");
  1258. ;
  1259. isnoise:    IS
  1260.     |    ;
  1261. ;
  1262. lbrace:        LBRACE =
  1263.             w_op($1->d_elm);
  1264. ;
  1265. lparen:        LPAREN    = 
  1266.             w_op($1->d_elm);
  1267. ;
  1268. of:        OF=
  1269.             w_key($1->d_elm);
  1270. ;
  1271. on:        ON =
  1272.             w_key($1->d_elm);
  1273. ;
  1274. pct:        PCT = 
  1275.             w_op($1->d_elm);
  1276. ;
  1277. period:        PERIOD =
  1278.             w_op($1->d_elm);
  1279. ;
  1280. repkword:    INTO    
  1281.     |    IN    
  1282.     |    ON    
  1283.     |    ;
  1284. ;
  1285. rparen:        RPAREN    =
  1286.             w_op($1->d_elm);
  1287. ;
  1288. to:        TO = 
  1289.             w_key($1->d_elm);
  1290. ;
  1291. retkword:    INTO    
  1292.     |    TO    
  1293.     |    ;
  1294. ;
  1295. until:        UNTIL    = 
  1296.             w_key($1->d_elm);
  1297. ;
  1298. where:        WHERE    = 
  1299.             w_key($1->d_elm);
  1300. ;
  1301. %%
  1302.  
  1303. # include    "tokens.y"
  1304.